/*
 *  cload.cpp
 *  EPPI-0.0
 *
 *  Created by Juan Carlos Garcia Orden on 15/11/07.
 *
 */

#include "cload.h"

CLoad::CLoad()
:	Component(),
	value(),
	numDofsOnePoint()
{}

// ***

CLoad::CLoad(ifstream & in, string bodyName, int di, const map<string,vector<string>,less<string> >* pset)
:	Component(),
	value()
{
	dim = di;
	
	string keyword;
	string auxs;	/** Auxiliary string */
	double auxd;	/** Auxiliary double */
	int i;
	map<string,vector<string>,less<string> > pointSets = *pset;
	vector<string> valueSt;
	string line;
	stringstream stnum;
	
	/** Extract the system name where the body is */
	string sysName = getStringHead(bodyName);	
	while (in >> keyword && keyword.compare("ENDLOAD") )
	{
		if(!keyword.compare("POINT"))
		{
			while (in >> auxs && auxs.compare("VALUE") )
			{
				/** If it does not have slash, add it with the system name */
				if(checkForSlash(auxs)==false) addSystemName(auxs,sysName);
				pointNames.push_back(auxs);	
			}		
		}
		else if(!keyword.compare("POINTSET"))
		{
			in >> auxs;	// Name of pointSet			
			for(i=0; i<pointSets[auxs].size(); ++i)	
			{
//				cout << "anadiendo punto " << pointSets[auxs][i] << " de pointset " << auxs << "\n";
				pointNames.push_back(pointSets[auxs][i]);	
			}
			in >> auxs;
		}
		if(!auxs.compare("VALUE"))
		{
			getline(in,line);
			stringstream iss(line);
			while (iss >> auxs )
			{
				valueSt.push_back(auxs);
			}
			for(i=0; i<valueSt.size(); ++i)
			{
				stnum << valueSt[i];
				stnum >> auxd;
				value.push_back(auxd);
				stnum.clear();
			}			
		}
	}
	
	
//	 cout << "Los valores de carga leidos son " << endl;
//	 for (i=0; i<value.size(); ++i)	cout << value[i] << endl;
}

// ***

void CLoad::calcFi(const vector<double>& qddot)
{}

// ***

void CLoad::calcFq(const int& nt)
{}

// ***

void CLoad::calcFt(const double& t, const double& grav, const int& gravDir)
{
	int i=0;
	int j=0;
	
//	cout << "numDofsOnePoint = " << numDofsOnePoint << endl;
	for(i=0; i<pointNames.size(); i++)
	{
		for(j=0; j<numDofsOnePoint; j++) Ft[j + numDofsOnePoint*i] = value[j];
	}
}

// ***

void CLoad::calcKi(double & partial_qddot)
{}

// ***

void CLoad::calcKq(int)
{}

// ***

void CLoad::calcKdq(double & partial_qdot)
{}

// ***

void CLoad::calcM(const vector<double>& q, const double& t)
{}

// ***

void CLoad::calcMLumped(const vector<double>& q, const double& t)
{}

// ***

void CLoad::setDofs(void)
{
	// It must not add any dof, but must set variable numDofs
	
 	map<string,Point*,less<string> >::iterator k;
	
	numDofsOnePoint = mPoints.begin()->second->countDofs();	// It is assumed that the two points have the same number of dofs
	numDofs = 0;
	for(k=mPoints.begin();k!=mPoints.end(); k++)	
	{
		numDofs += k->second->countDofs();
	}
//	cout << "numDofs en cload is " << numDofs << endl;
}

// ***

// void CLoad::initializeGlobalDofs(vector<double> &q_in)
// {
// 	if(q.size()==0)		/** If q has not been initialized yet */
// 	{
// 		q.resize(numDofs);
// 	}
// 	// A force must not initialize any dof.  This is a job for bodies.	
// }

// ***

void CLoad::initializeGlobalDofs(vector<double> &q_in, vector<double> &dq_in, const double & t )
{
	int i=0;
	
	//	t = time;
	if(q.size()==0)		/** If q has not been initialized yet, put dofs to 0 */
	{
		q.resize(numDofs);
		dq.resize(numDofs);		
	}
	else if(dq.size()==0)
	{
		for(i=0; i<q.size(); i++)	dq_in[ localGlob[i] ] = 0.0 ;	/** From rest. Other initial condition  TO BE DONE. */
	}	
}

// ***

void CLoad::setMatAtComp(Material* ma)
{}

// ***

void CLoad::initializeCompRes(const bool& st, const double& grav, const int& gravDir, const bool augLagFlag)
{
	Ft.resize(numDofs);
	if (numDofs!=value.size()*pointNames.size())
	{
		cout << "value.size " << value.size() << endl;
		cout << "poitNames.size " << pointNames.size() << endl;
		cout << "numDofs = " << numDofs << endl;
		cout << "ERROR** Number of dofs does not match the dimension of the load vector \n";
	}
}

// ***

//void CLoad::initializeCompTang(const bool& st,  const bool&)
void CLoad::initializeCompTang(const bool& st)
{}

// ***

void CLoad::calcEner(double& Ekin, double& Epot, double& Econ, double& Eext, double& Eamb, double& Dint, double& grav, int& gravDir, vector<double>& q_in, vector<double>& dq_in)
{
	
	int i=0;
	int j=0;

	for(i=0; i<pointNames.size(); i++)
	{
		for(j=0; j<numDofsOnePoint; j++) Eext -= q_in[localGlob[j + numDofsOnePoint*i]] * value[j];
	}

}

// ***

void CLoad::calcEntropy(double& Entropy, double& EntropyAmb)
{}

// ***

void CLoad::calcAM(vector<double>& am, vector<double>& q_in, vector<double>& dq_in)
{}	

// ***

void CLoad::updateComp(void)
{}

// ***

void CLoad::setIniDofs(vector<double>&)
{}

// ***

void CLoad::calcPhi(const vector<double>&)
{}

// ***

void CLoad::calcDPhi(const vector<double>&)
{}

// ***

void CLoad::calcMSmooth(const vector<double>& q_in, const double& t)
{}

// ***

void CLoad::calcFSmooth(const vector<double>& q_in, const vector<double>& dq_in, const double& t)
{}

int CLoad::checkState()
{
return 0;
}
